﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AuctionDataLayer.Models;

namespace AuctionDataLayer
{
    class DataLayerRepository
    {
        AuctionDBDataContext m_db = new AuctionDBDataContext();

        public IEnumerable<Bid> GetAllPendingBidsByDate(DateTime date)
        {
            var result = from item in m_db.Bids
                         where item.Date.Day == date.Day &&
                               item.Date.Month == date.Month &&
                               item.Date.Year == date.Year &&
                               item.StateId == 1
                         select item;
            return result;
        }

        public IEnumerable<Room> GetAllRooms()
        {
            var result = from item in m_db.Rooms
                         where item.Deleted == false
                         select item;
            return result;
        }

        public IEnumerable<AvailableBidTime> GetAvailableBidTimes()
        {
            var result = from item in m_db.AvailableBidTimes
                         select item;
            return result;
        }

        public UserInGroup GetUserInGroupById(int userId, int groupId)
        {
            var result = (from item in m_db.UserInGroups
                          where item.UserId == userId && item.GroupId == groupId && item.ActiveMember == true
                          select item).SingleOrDefault();
            return result;
        }

        public Group GetGroupById(int id)
        {
            var result = (from item in m_db.Groups
                          where item.Id == id
                          select item).SingleOrDefault();
            return result;
        }

        public void AddToUserInGroupByBid(UserInGroupBid model)
        {
            if (model != null)
            {
                m_db.UserInGroupBids.InsertOnSubmit(model);
                m_db.SubmitChanges();
            }
        }

        public void UpdateUserInGroup(List<ToPayModel> list, int groupId, int BidId)
        {
            var group = GetGroupById(groupId);
            if (list != null && group != null)
            {
                foreach (var item in list)
                {
                    var userToUpdate = GetUserInGroupById(item.userId, group.Id);
                    userToUpdate.CreditAddedSpent += item.amountToPay;

                    UserInGroupBid model = new UserInGroupBid();
                    model.UserInGroupId = userToUpdate.Id;
                    model.BidId = BidId;
                    model.GroupBalance = group.Balance;
                    model.MembersCredit = userToUpdate.CreditAdded - userToUpdate.CreditAddedSpent;
                    model.MembersCreditPaid = item.amountToPay;
                    AddToUserInGroupByBid(model);

                    m_db.SubmitChanges();
                }
                //Update group info
                group.Balance -= list.Select(x => x.amountToPay).Sum();
                m_db.SubmitChanges();
            }
        }

        public List<UserInGroup> GetMembersOfGroupById(int id)
        {
            var result = (from item in m_db.UserInGroups
                          where item.GroupId == id && item.ActiveMember == true
                          select item).ToList();
            return result;
        }

        public List<UserInGroup> GetMembersOfGroupByIdAll(int id)
        {
            var result = (from item in m_db.UserInGroups
                          where item.GroupId == id
                          select item).ToList();
            return result;
        }

        public Bid getBidById(int id)
        {
            var result = (from item in m_db.Bids
                          where item.Id == id
                          select item).SingleOrDefault();
            return result;
        }

        public IEnumerable<Bid> getBidByIdForAnyRoom(int id, int winnerId)
        {
            var result = from item in m_db.Bids
                         where item.AnyRoomId == id && item.Id != winnerId                         
                         select item;
            return result;
        }

        public void deleteAllBid(IEnumerable<Bid> model)
        {
            if (model != null)
            {
                m_db.Bids.DeleteAllOnSubmit(model);
                m_db.SubmitChanges();
            }
        }

        public void updateWinnerAnyRoomBid(Bid model, int amount)
        { 
            var result = getBidById(model.Id);
            if(result != null)
            {
                result.PaidAmount = amount;
                result.AnyRoom = false;
                result.AnyRoomId = result.Id;
                result.StateId = 2;
                m_db.SubmitChanges();
            }
        }

        public void updateWinnerBid(Bid model, int amount)
        {
            var result = getBidById(model.Id);
            if (result != null)
            {
                result.PaidAmount = amount;
                result.StateId = 2;
                m_db.SubmitChanges();
            }
        }

        public UserInGroup GetUserInGroupById(int id)
        {
            var result = (from item in m_db.UserInGroups
                          where item.Id == id
                          select item).SingleOrDefault();
            return result;
        }

        public UserInGroupBid GetUserInGroupBidById(int userInGroupId, int bidId)
        {
            var result = (from item in m_db.UserInGroupBids
                          where item.UserInGroupId == userInGroupId && item.BidId == bidId
                          select item).SingleOrDefault();
            return result;
        }

        public UserInGroupBid GetUserInGroupBidByIdOnly(int id)
        {
            var result = (from item in m_db.UserInGroupBids
                          where item.Id == id
                          select item).SingleOrDefault();
            return result;
        }

        //m_rep.updateWinnerUserInGroup(userInGroup, userInGroupBid.MembersCreditPaid, winner.amountToPay);
        public void updateWinnerUserInGroup(UserInGroup model, int creditAddedSpent)
        {
            var result = GetUserInGroupById(model.Id);
            if (result != null)
            {
                result.CreditAddedSpent = creditAddedSpent;
                m_db.SubmitChanges();
            }
        }

        public User GetUserById(int id)
        {
            var result = (from item in m_db.Users
                          where item.Id == id
                          select item).SingleOrDefault();
            return result;
        }

        public void UpdateUserBalance(int userId, int amount)
        {
            var result = GetUserById(userId);
            if (result != null)
            {
                result.Balance = amount;
                m_db.SubmitChanges();
            }
        }

        public void UpdateGroupBalance(int id, int amount)
        {
            var result = GetGroupById(id);
            if (result != null)
            {
                result.Balance = amount;
                m_db.SubmitChanges();
            }
        }

        public void DeleteUserInGroupBidById(int id)
        {
            var result = GetUserInGroupBidByIdOnly(id);
            if (result != null)
            {
                m_db.UserInGroupBids.DeleteOnSubmit(result);
                m_db.SubmitChanges();
            }
        }
        
        public void UpdateUserInGroupBidById(int id, int newMemberCreditPaid)
        {
            var result = GetUserInGroupBidByIdOnly(id);
            if (result != null)
            {
                result.MembersCreditPaid = newMemberCreditPaid;
                m_db.SubmitChanges();
            }
        }

        public void DeleteUserInGroupBids(List<UserInGroupBid> model)
        {
            if (model != null)
            {
                m_db.UserInGroupBids.DeleteAllOnSubmit(model);
                m_db.SubmitChanges();
            }
        }

        public void UpdateBidState(Bid model, int state)
        {
            var result = getBidById(model.Id);
            if (result != null)
            {
                result.StateId = state;
                m_db.SubmitChanges();
            }
        }

        public void UpdateUserInGroupBalance(UserInGroup model)
        {
            var result = GetUserInGroupById(model.UserId, model.GroupId);
            if (result != null)
            {
                result.CreditAddedSpent = model.CreditAddedSpent;
                m_db.SubmitChanges();
            }
        }

        public void deleteUserInGroupBid(UserInGroupBid model)
        {
            var result = GetUserInGroupBidById(model.UserInGroupId, model.BidId);
            if (result != null)
            {
                m_db.UserInGroupBids.DeleteOnSubmit(result);
                m_db.SubmitChanges();
            }
        }

        public IEnumerable<UserInGroupBid> GetUserInGroupBidById(IEnumerable<UserInGroup> userInGroupList, int bidId)
        {
            var result = from item in m_db.UserInGroupBids
                         where item.BidId == bidId && userInGroupList.Contains(item.UserInGroup)
                         select item;
            return result;
        }

        public IEnumerable<UserInGroupBid> GetUsersInGroupBidByIdOnly(int bidId)
        {
            var result = from item in m_db.UserInGroupBids
                         where item.BidId == bidId
                         select item;
            return result;
        }

        public void UpdateUserInGroupBidId(UserInGroupBid model, Bid winnerBid)
        {
            var result = GetUserInGroupBidByIdOnly(model.Id);
            if (result != null)
            {
                result.Bid = winnerBid;
                m_db.SubmitChanges();
            }
        }

        public void AddNotifications(List<Notification> model)
        {
            if (model != null)
            {
                m_db.Notifications.InsertAllOnSubmit(model);
                m_db.SubmitChanges();
            }
        }
    }
}
